Creating Background Processes

By Alex Schendel

 

Introduction

Perhaps you have tried running an application on your phone (or whatever other device you may have), when suddenly it stops responding… Trouble! Now you either wait and see if it will fix itself or you kill the app, which tends to pose a real dilemma. When an application stops responding, this means that it is doing too much work on its main or UI (User Interface) thread. The main or UI thread of an application is basically the part of processor time and memory that is dedicated to your main activity. The main thread will always have the greatest amount of CPU resources available to it because it runs the part of the app that the user interacts with(hence User Interface Thread). When the app “stops responding”, it is running so much work on its main thread that it basically falls behind on processing all of the requests given to it. Luckily there is a way to still complete processor intensive requests without causing your application to freeze. Welcome background processes!

 

Background processes are separate threads from the main thread which are best suited for completing tasks which either take a long time (such as a large file download), or require many calculations (such as complex game movements).

 

This tutorial will show you how to use an AsyncTask to run a process in the background.

 

AsyncTask

 

An AsyncTask is the easiest and simplest way to run a process in the background. Normally such tasks would require manipulation of the Thread and Handler classes, but AsyncTask does all of this for you.

 

For this example can make use of a horizontal ProgressBar to show the “progress” of the AsyncTask.

 

1.     Create an Empty Activity

2.     Add a horizontal ProgressBar to your layout and make its width “match_parent”

3.     Ensure that the ProgressBar has an id and call it from the Activity class

4.     Create a new class called AsyncClass and make it extend AsyncTask. This will take params Void and return progress as an Integer and return a Void, in the form: AsyncTask<Void,int,Void>. By extending AsyncTask, you will be required to use the method “doInBackground”.

Note: the <Void,Integer,Void> following the AsyncTask are the arrays that the AsyncTask use for parameters, progress updates, and return values, respectively.

 

5. Now it is time to receive the ProgressBar that the AsyncTask will update. This can be done by making a constructor that takes a ProgressBar as a parameter and sets a global variable.

6. Now it is time to get ready to receive progress updates. This can be achieved by adding the method “onProgressUpdate”, and then we can set the progressBar max to values[0], where values is the Integer array that will be published to the UI thread when the progress is updated.

7. Now we can tell the doInBackground() method what is should do, which is nothing besides update the progressBar and then sleep(unless you have something you wish to use it for currently). The method publishProgress() will allow us to tell the UI thread what our current progress is. The parameters we provide will be turned into an array of values and passed to the onProgressUpdate() method.

Now we have a class that will run in the background and increase the percentage of a progressBar every tenth of a second.

 

6. Now we must create an instance of this class to run in the MainActivity. Still, with an instance, we must tell it to execute its doInBackground method, so after we initialize the instance of the AsyncClass, we must call its execute() method. Normally, this would take parameters and create an array of them to pass to the doInBackground method, but since we called a constructor for it prior to executing its task, there is no need to hand it parameters.

 

7. Bask in the glorious progressBar as it moves across the screen… Oh I’m sorry did you actually want to use your background thread for something useful? Fine, then I suppose we should try and do that then?

 

8. In order to make use of this task, we must allow it to return values to the MainActivity. This is achieved through the third parameter when creating the AsyncClass. For example, we can return a String to the MainActivity by changing the third parameter to “String”.

9. Now we can return a String to the MainActivity, but the point of an Asynchronous Task is that it is out of sync from the main thread. Thus, we do not know when the task will be completed and the String returned. You could say that since the progressBar increases one percent every tenth of a second then it would finish in 10 seconds, but what about other tasks that require real computing? This is where Interfaces come in. We will need to make a new Class,  but instead of calling it a class, we will replace that with interface. We can also name it something like OnTaskCompleted and give it a callback function called onTaskCompleted().

10. Now in order to make the MainActivity have this callback function, we must implement it in the MainActivity. Which will force us to also implement the callback method onTaskCompleted().

11. If this method is called when the AsyncTask is complete, then we could just take the String from it, right? Well not quite yet. We still need to know WHEN the AsyncTask will be completed, which can be achieved by using onPostExecute().

12. Notice that I also changed the String that doInBackground returned to “Task Completed”. This String will be passed to onPostExecute when doInBackground returns. However, we want to pass this String to the MainActivity. So we will need out OnTaskCompleted interface to help us with that. Let’s make it accept a String parameter in its onTaskCompleted() method.

13. Now we can receive a String through the onTaskCompleted() callback in our MainActivity.

14. Now we must use this interface in our AsyncClass to call that function in our MainActivity and pass it the final result of a String.

c

15. In order for the AsyncClass to have an instance of the onTaskCompleted to call, we must receive the MainActivity’s instance through the constructor and initialize the listener accordingly.

16. Now when we run it, when the progressBar is full, the MainActivity will be passed a String. For my example, it will be passed “Task Completed”. We can test it by making a Toast display the String returned from the MainActivity.

This is the result:

Screenshot_2016-08-03-14-41-25[1].png

Now you can go and do complex calculations while allowing the user to know how close to completion the process is, and preventing the calculations from freezing the main thread! Example of this use of the Async Task to edit images which would otherwise freeze the UI thread for about 15 seconds:

More reading on AsyncTasks

 

More reading on Keeping Applications Responsive (background calculations)